package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.common.constant.MessageConstant;
import com.itheima.common.constant.RedisConstant;
import com.itheima.common.entity.PageResult;
import com.itheima.common.entity.QueryPageBean;
import com.itheima.common.exception.DataNotFoundException;
import com.itheima.common.exception.FileUploadFailedException;
import com.itheima.common.exception.RedisNotAvailableException;
import com.itheima.common.utils.AliOssUtil;
import com.itheima.mapper.SetmealMapper;
import com.itheima.mapper.Setmeal_CheckgroupMapper;
import com.itheima.pojo.Setmeal;
import com.itheima.service.SetmealService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnectionCommands;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

@Service
@Slf4j
public class SetmealServiceimpl implements SetmealService {
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;
    @Value("${freemarker.out.path}")
    private String outPutPath;
    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    Setmeal_CheckgroupMapper setmeal_checkgroupMapper;
    @Autowired
    SetmealMapper setmealMapper;
    //查找套餐-----------------
    @Override
    public Setmeal findById(Integer id) {
      Setmeal setmeal=setmealMapper.findById(id);
      if (setmeal == null ) {
            // 如果未查询到数据，抛出异常
            throw new DataNotFoundException(MessageConstant.QUERY_SETMEAL_FAIL);
        }
        return setmeal;
    }
//删除套餐====================================================
    @Override
    public void deleteById(Integer id) {
        Setmeal setmeal = findById(id);
        // 判断图片信息是否存在
        String imgUrl = setmeal.getImg();
        if (imgUrl != null && !imgUrl.isEmpty()) {
            // 将图片信息添加到redis缓存中(无论是否已经存在) --> 阿里云图片集合
            log.info("添加redis缓存到Aliyun图片集合:{}", imgUrl);
            redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_RESOURCES).add(imgUrl);
            // 将图片路径从redis缓存中移除(无论是否已经存在) --> 数据库图片集合
            log.info("移除redis缓存到数据库图片集合:{}", imgUrl);
            redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_DB_RESOURCES).remove(imgUrl);
        }
        setmealMapper.deleteById(id);
        setmeal_checkgroupMapper.deleteBySetmealId(id);
    }
//添加套餐====================================================================
    @Override
    public void addSetmeal(Setmeal setmeal, ArrayList<Long> ids) {
        setmealMapper.addSetmeal(setmeal);

        String imgUrl = setmeal.getImg();
        if (imgUrl != null && !imgUrl.isEmpty()) {
            redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_DB_RESOURCES).add(imgUrl);
        }
       for(Long id:ids){
           setmealMapper.addGroup(setmeal.getId(),id);
       }
        //当添加套餐后需要重新生成静态页面（套餐列表页面、套餐详情页面）
        generateMobileStaticHtml();

    }
    public void generateMobileStaticHtml(){
        List<Setmeal>list=setmealMapper.getAll();
        //需要生成套餐列表静态页面
        generateMobileSetmealListHtml(list);
        //需要生成套餐详情静态页面
        generateMobileSetmealDetailHtml(list);


    }
    public void generateMobileSetmealListHtml(List<Setmeal> list){
        Map map = new HashMap();
        //为模板提供数据，用于生成静态页面
        map.put("setmealList",list);
        generteHtml("mobile_setmeal.ftl","m_setmeal.html",map);
    }
    public void generateMobileSetmealDetailHtml(List<Setmeal> list){
        for (Setmeal setmeal : list) {
            Map map = new HashMap();
            map.put("setmeal",setmealMapper.findById(setmeal.getId()));
            generteHtml("mobile_setmeal_detail.ftl","setmeal_detail_" + setmeal.getId() + ".html",map);
        }
    }
    public void generteHtml(String templateName,String htmlPageName,Map map){
        Configuration configuration = freeMarkerConfigurer.getConfiguration();//获得配置对象
        Writer out = null;
        try {
            Template template = configuration.getTemplate(templateName);
            //构造输出流
            out = new FileWriter(new File(outPutPath + "/" + htmlPageName));
            //输出文件
            template.process(map,out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//分页查询-------------------------------------------------
    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        PageHelper.startPage(queryPageBean.getCurrentPage(),queryPageBean.getPageSize());
        Page<Setmeal> setmeals= setmealMapper.findPage(queryPageBean.getQueryString());
        return  new PageResult(setmeals.getTotal(),setmeals.getResult());
    }
//更新套餐==================================================================
    @Override
    public void updateSetmeal(ArrayList<Integer> ids, Setmeal setmeal) {
        SetOperations setOperations = redisTemplate.opsForSet();
        Setmeal oldSetmeal =findById(setmeal.getId());
        String oldImgUrl =oldSetmeal.getImg();
        setmealMapper.update(setmeal);
        String imgUrl=setmeal.getImg();
        if(!Objects.equals(oldImgUrl,imgUrl)){
            if (oldImgUrl != null && !oldImgUrl.isEmpty()) {

                // 将旧图片信息添加到redis缓存中(无论是否已经存在) --> 阿里云图片集合
                setOperations.add(RedisConstant.SETMEAL_PIC_RESOURCES,oldImgUrl);
                // 将旧图片路径从redis缓存中移除(无论是否已经存在) --> 数据库图片集合
                setOperations.remove(RedisConstant.SETMEAL_PIC_RESOURCES,oldImgUrl);
            }
            if (imgUrl != null && !imgUrl.isEmpty()) {
               setOperations.add(RedisConstant.SETMEAL_PIC_DB_RESOURCES,imgUrl);
            }

        }
        setmeal_checkgroupMapper.deleteBySetmealId(setmeal.getId());
        if(ids!=null&&!ids.isEmpty()){
            for(int i=0;i<ids.size();i++){
                setmeal_checkgroupMapper.addCheckGroup(setmeal.getId(),ids.get(i));
            }
        }

    }
//下载图片---------------------------------------------------------------------
    @Override
    public String upload(MultipartFile imgFile) {
        // 判断当前Redis是否可以使用
       if (!isRedisAvailable()) {
            throw new RedisNotAvailableException(MessageConstant.PIC_UPLOAD_FAIL);
        }
        try {
            // 获取文件后缀,生成新的文件名
           // int index1=imgFile.getOriginalFilename().lastIndexOf(".");
            int index = Objects.requireNonNull(imgFile.getOriginalFilename()).lastIndexOf(".");
            String suffix = imgFile.getOriginalFilename().substring(index);
            String fileName = UUID.randomUUID().toString() + suffix;
            // 上传图片,获取图片的url
            String imgUrl = aliOssUtil.upload(imgFile.getBytes(), fileName);
            // 将token添加到redis缓存当中
            log.info("添加redis缓存到aliyun图片集合:{}", imgUrl);
            redisTemplate.boundSetOps(RedisConstant.SETMEAL_PIC_RESOURCES).add(imgUrl);
            // 返回图片的url
            return imgUrl;
        } catch (IOException e) {
            throw new FileUploadFailedException(MessageConstant.PIC_UPLOAD_FAIL);
        }
    }



    public boolean isRedisAvailable() {
        try {
            // 使用 PING 命令检查 Redis 连接
            String result = redisTemplate.execute(RedisConnectionCommands::ping);
            return "PONG".equals(result);
        } catch (Exception e) {
            log.error("Redis 连接不可用");
            return false;
        }
    }

}
